<template>
  <a-modal v-model:visible="visible" :title="title" :footer="null" width="60%" :closable="false">
    <a-row :gutter="16">
      <a-col :span="4">
      </a-col>
      <a-col :span="5">
        <a-card :bordered="false" style="text-align: center" :bodyStyle="{'padding': '5px'}">
          <a-card-meta>
            <template #title>
              <a-avatar :size="40" :style="{'background-color': !testInfo.percent ? '#CCC' : testInfo.connected ? '#52c41a' : '#ff4d4f'}">
                <template #icon>
                  <question-circle-outlined/>
                </template>
              </a-avatar>
            </template>
            <template #description>{{ !formState['type'] ? '_' : formState['type'] }}</template>
          </a-card-meta>
        </a-card>
      </a-col>
      <a-col :span="6">
        <a-card :bordered="false" style="text-align: center" :bodyStyle="{'padding': '5px'}">
          <a-card-meta>
            <template #description>
              <a-progress :percent="testInfo.percent" :show-info="false"
                          :status="testInfo.connected ? 'success' : 'exception'">
              </a-progress>
            </template>
          </a-card-meta>
        </a-card>
      </a-col>
      <a-col :span="5">
        <a-card :bordered="false" style="text-align: center" :bodyStyle="{'padding': '5px'}">
          <a-card-meta>
            <template #title>
              <a-avatar :size="40" :style="{'background-color': !testInfo.percent ? '#CCC' : testInfo.connected ? '#52c41a' : '#ff4d4f'}">
                <template #icon>
                  <database-outlined/>
                </template>
              </a-avatar>
            </template>
            <template #description>{{ $t('common.source') }}</template>
          </a-card-meta>
        </a-card>
      </a-col>
      <a-col :span="3">
      </a-col>
    </a-row>
    <a-form :model="formState" :validate-messages="validateMessages" v-bind="layout" @finish="handlerSave()">
      <a-tabs v-model:activeKey="activeKey" centered>
        <a-tab-pane key="type" style="text-align: center;">
          <template #tab>
            <span>
              <appstore-outlined/> {{ $t('common.source') }}
            </span>
          </template>
          <a-radio-group v-model:value="formState.type">
            <a-row :gutter="[16,8]">
              <a-col v-for="plugin in plugins" :span="6" v-bind:key="plugin.name">
                <a-radio-button :value="plugin.name">
                  {{ plugin.name }}
                </a-radio-button>
              </a-col>
            </a-row>
          </a-radio-group>
        </a-tab-pane>
        <a-tab-pane :disabled="!formState.type" key="configure">
          <template #tab>
            <span>
              <setting-outlined/> {{ $t('common.configure') }}
            </span>
          </template>
          <a-form-item :name="['name']" :label="$t('common.name')" :rules="[{ required: true }]">
            <a-input v-model:value="formState.name"/>
          </a-form-item>
          <!-- <a-form-item :name="['protocol']" label="Protocol" :rules="[{ required: true }]">
            <a-select ref="select" v-model:value="formState.protocol" style="width: 120px">
              <a-select-option value="HTTP">HTTP</a-select-option>
              <a-select-option value="HTTPS">HTTPS</a-select-option>
              <a-select-option value="SSH">SSH</a-select-option>
            </a-select>
          </a-form-item> -->
          <a-form-item :name="['host']" :label="$t('common.host')" :rules="[{ required: true }]">
            <a-input v-model:value="formState.host"/>
          </a-form-item>
          <a-form-item :name="['port']" :label="$t('common.port')" :rules="[{type: 'number', min: 0, max: 65535}]">
            <a-input-number v-model:value="formState.port"/>
          </a-form-item>
        </a-tab-pane>
        <a-tab-pane :disabled="!formState.type" key="authorization">
          <template #tab>
            <span>
              <lock-outlined/> {{ $t('common.authorization') }}
            </span>
          </template>
          <a-form-item :name="['username']" :label="$t('common.username')">
            <a-input v-model:value="formState.username"/>
          </a-form-item>
          <a-form-item :name="['password']" :label="$t('common.password')">
            <a-input v-model:value="formState.password"/>
          </a-form-item>
          <a-form-item :name="['ssl']" label="SSL">
            <a-switch v-model:checked="formState.ssl"/>
          </a-form-item>
        </a-tab-pane>
        <a-tab-pane :disabled="!formState.type" key="advanced">
          <template #tab>
            <span>
              <group-outlined/> {{ $t('common.advanced') }}
            </span>
          </template>
          <a-form-item :name="['catalog']" :label="$t('common.catalog')">
            <a-input v-model:value="formState.catalog"/>
          </a-form-item>
          <a-form-item :name="['database']" :label="$t('common.database')">
            <a-input v-model:value="formState.database"/>
          </a-form-item>
        </a-tab-pane>
        <a-tab-pane :disabled="!formState.type" key="custom">
          <template #tab>
            <span>
              <inbox-outlined/> {{ $t('common.custom') }}
            </span>
          </template>
          <a-form-item style="margin-bottom: 10px;">
            <a-button size="small" type="primary" shape="circle" @click="handlerPlusConfigure()">
              <PlusOutlined/>
            </a-button>
          </a-form-item>
          <a-form-item v-for="(element, index) in configure" :key="index" style="margin-bottom: 5px;">
            <a-row :gutter="24">
              <a-col :span="12">
                <a-form-item :label="$t('common.field')" :name="['configure', index, 'field']"
                             :key="['configure', index, 'field']" style="margin-bottom: 5px;">
                  <a-input v-model:value="element.field"></a-input>
                </a-form-item>
              </a-col>
              <a-col :span="10">
                <a-form-item :label="$t('common.value')" :name="['configure', index, 'value']"
                             :key="['configure', index, 'value']" style="margin-bottom: 5px;">
                  <a-input v-model:value="element.value"></a-input>
                </a-form-item>
              </a-col>
              <a-col :span="2">
                <a-form-item style="margin-bottom: 5px;">
                  <a-button size="small" type="primary" shape="circle" danger @click="handlerMinusConfigure(element)">
                    <MinusCircleOutlined/>
                  </a-button>
                </a-form-item>
              </a-col>
            </a-row>
          </a-form-item>
        </a-tab-pane>
      </a-tabs>
      <a-form-item :wrapper-col="{ ...layout.wrapperCol, offset: 8 }" style="margin-top: 20px; margin-bottom: -5px;">
        <a-space style="width: 100%">
          <a-button key="cancel" danger size="small" :disabled="connectionLoading" @click="handlerCancel()">
            {{ $t('common.cancel') }}
          </a-button>
          <a-button key="test" type="primary" size="small" :loading="connectionLoading" @click="handlerTest()">
            {{ $t('common.test') }}
          </a-button>
          <a-button key="submit" type="primary" size="small" :disabled="!testInfo.connected" html-type="submit">
            {{ $t('common.save') }}
          </a-button>
        </a-space>
      </a-form-item>
    </a-form>
  </a-modal>
</template>

<script lang="ts">
import {SourceModel} from "@/model/SourceModel";
import {SourceService} from "@/services/SourceService";
import {emptySource} from "@/views/pages/admin/source/SourceGenerate";
import {message} from "ant-design-vue";
import {defineComponent, reactive, ref} from "vue";
import {Configure} from "@/model/Configure";
import {Arrays} from "@/common/Arrays";

interface TestInfo
{
  connected: boolean,
  percent: number
}

export default defineComponent({
  name: "SourceInfoView",
  props: {
    isVisible: {
      type: Boolean,
      default: () => false
    },
    id: {
      type: Number,
      default: () => 0
    }
  },
  setup()
  {
    const layout = {
      labelCol: {span: 6},
      wrapperCol: {span: 12},
    };
    const validateMessages = {
      required: '${label} is required!',
      number: {
        range: '${label} must be between ${min} and ${max}',
      },
    };

    return {
      activeKey: ref('type'),
      validateMessages,
      layout
    };
  },
  components: {},
  data()
  {
    return {
      title: '',
      isUpdate: false,
      formState: {} as SourceModel,
      plugins: [],
      testInfo: {} as TestInfo,
      connectionLoading: false,
      configure: [] as Configure[]
    }
  },
  created()
  {
    if (this.id <= 0) {
      this.title = 'Create New Source';
      this.formState = reactive(emptySource);
    }
    else {
      this.title = 'Modify Source';
      this.isUpdate = true;
    }
    this.handlerInitialize();
  },
  methods: {
    handlerInitialize()
    {
      if (this.id > 0) {
        new SourceService().getById(this.id)
          .then(response => {
            if (response.status) {
              this.formState = reactive(response.data);
              if (response.data.configures) {
                Object.keys(response.data.configures).forEach((value) => {
                  const configure: Configure = {
                    field: value,
                    value: response.data.configures[value]
                  };
                  this.configure.push(configure);
                });
              }
            }
          });
      }
      new SourceService().getPlugins()
        .then(response => {
          if (response.status) {
            this.plugins = response.data;
          }
        });
    },
    handlerCancel()
    {
      this.visible = false;
    },
    handlerSave()
    {
      this.formState.configures = Arrays.arrayToObject(this.configure);
      new SourceService()
        .saveAndUpdate(this.formState, this.isUpdate)
        .then((response) => {
          if (response.status) {
            message.success("Create successful");
            this.visible = false;
          }
        });
    },
    handlerTest()
    {
      this.connectionLoading = true;
      this.formState.configures = Arrays.arrayToObject(this.configure);
      new SourceService()
        .testConnection(this.formState)
        .then((response) => {
          this.testInfo.percent = 100;
          if (response.status) {
            message.success("Test successful");
            this.testInfo.connected = true;
          }
          else {
            message.error(response.message);
            this.testInfo.connected = false;
          }
        })
        .finally(() => {
          this.connectionLoading = false;
        });
    },
    handlerPlusConfigure()
    {
      const configure: Configure = {field: '', value: ''};
      this.configure.push(configure);
    },
    handlerMinusConfigure(configure: Configure)
    {
      const index = this.configure.indexOf(configure);
      if (index !== -1) {
        this.configure.splice(index, 1);
      }
    }
  },
  computed: {
    visible: {
      get(): boolean
      {
        return this.isVisible
      },
      set(value: boolean)
      {
        this.$emit('close', value)
      }
    }
  }
});
</script>
